package com.dataimport.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dataimport.entity.sourceentity.LibraryPassThroughRecord;
import com.dataimport.entity.sourceentity.SchoolCalendar;
import com.dataimport.entity.sourceentity.StudentBaseInfo;
import com.dataimport.entity.targetentity.LibraryAccessRecords;
import com.dataimport.mapper.LibraryAccessRecordsMapper;
import com.dataimport.mapper.LibraryPassThroughRecordMapper;
import com.dataimport.mapper.SelectSchoolCalendarMapper;
import com.dataimport.mapper.StudentBaseInfoMapper;
import com.dataimport.service.LibraryAccessRecordsService;
import com.dataimport.utils.GetDifferHour;
import com.dataimport.utils.HasNullFieldUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 库访问记录服务impl
 *
 * @author 章珑赢
 * @date 2022/09/29
 */
@Service
public class LibraryAccessRecordsServiceImpl extends ServiceImpl<LibraryAccessRecordsMapper, LibraryAccessRecords> implements LibraryAccessRecordsService {
    @Autowired
    private LibraryPassThroughRecordMapper libraryPassThroughRecordMapper;
    @Autowired
    private StudentBaseInfoMapper studentBaseInfoMapper;
    @Autowired
    private SelectSchoolCalendarMapper selectSchoolCalendarMapper;
    @Override
    public void dealWitLibraryAccessRecords() {
        DynamicDataSourceContextHolder.push("mysql2");
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        查询当前学期
        String begin =  formatter.format(new Date());
        String end = formatter.format(new Date());
        LambdaQueryWrapper<SchoolCalendar> schoolCalendarLambdaQueryWrapper = new LambdaQueryWrapper<>();
        schoolCalendarLambdaQueryWrapper.le(SchoolCalendar::getKsrq,begin).ge(SchoolCalendar::getJsrq,end);
        SchoolCalendar schoolCalendar = selectSchoolCalendarMapper.selectOne(schoolCalendarLambdaQueryWrapper);
        //通过校历获取到当前学期的时间范围
//        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        String beginTime=formatter.format(schoolCalendar.getKsrq());
//        String endTime=formatter.format(schoolCalendar.getJsrq());
        //   根据当前时间查询所有同学的本学期图书馆通行记录
        LambdaQueryWrapper<LibraryPassThroughRecord> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.between(LibraryPassThroughRecord::getTxsj,DateUtil.parse(schoolCalendar.getKsrq()),DateUtil.parse(schoolCalendar.getJsrq()));
        lambdaQueryWrapper.orderByAsc(LibraryPassThroughRecord::getTxsj);
            List<LibraryPassThroughRecord> libraryPassThroughRecords = libraryPassThroughRecordMapper.selectList(lambdaQueryWrapper);
        // 把所有同学本学期的数据放入map中，减少数据库访问量
        Map<String,List<LibraryPassThroughRecord>>studentLibraryInfosMap = new HashMap<>();
        for (LibraryPassThroughRecord libraryPassThroughRecord : libraryPassThroughRecords) {
            List<LibraryPassThroughRecord> collect = libraryPassThroughRecords.stream().parallel().filter(LibraryPassThroughRecord
                    -> libraryPassThroughRecord.getRybm().equals(libraryPassThroughRecord.getRybm())).collect(Collectors.toList());
            studentLibraryInfosMap.put(libraryPassThroughRecord.getRybm(),collect);
        }
        //根据学生id，进行数据的清洗和封装
        List< LibraryAccessRecords> libraryAccessRecordsList = new ArrayList<>();
        List<StudentBaseInfo> studentBaseInfos = studentBaseInfoMapper.selectList(null);
        LibraryAccessRecords libraryAccessRecord= new LibraryAccessRecords();
        List<Integer> reduceList = new ArrayList<>();
        for (StudentBaseInfo studentBaseInfo : studentBaseInfos) {
            List<LibraryPassThroughRecord> enterCollect = studentLibraryInfosMap.get(studentBaseInfo.getXh()).stream().parallel().filter(LibraryPassThroughRecord -> LibraryPassThroughRecord.getJclx().equals("1")).collect(Collectors.toList());
            List<LibraryPassThroughRecord> outCollect = studentLibraryInfosMap.get(studentBaseInfo.getXh()).stream().parallel().filter(LibraryPassThroughRecord -> LibraryPassThroughRecord.getJclx().equals("2")).collect(Collectors.toList());
            if(enterCollect.size()>outCollect.size()){
                enterCollect.remove(enterCollect.get(enterCollect.size()-1));
            } else if(enterCollect.size()<outCollect.size()){
                enterCollect.remove(enterCollect.get(0));
            }
            if(enterCollect.size()==0||outCollect.size()==0){
                libraryAccessRecord.setUserCode(studentBaseInfo.getXh());
                libraryAccessRecord.setLibraryAccessTimes(outCollect.size());
                libraryAccessRecord.setLibraryAccessDuration(0);
                libraryAccessRecord.setLibraryAccessBeatRate(0);
                reduceList.add(0);
                libraryAccessRecordsList.add(libraryAccessRecord);
                continue;
            }
            List<Integer>differHour= new ArrayList<>();
            for(int flag=0;flag<outCollect.size();flag++){
                differHour.add(GetDifferHour.getDifferHour(DateUtil.parse(enterCollect.get(flag).getTxsj()), DateUtil.parse(outCollect.get(flag).getTxsj())));
            }
            Integer reduce = (differHour.stream().reduce(0, Integer::sum));
            reduceList.add(reduce);
            libraryAccessRecord.setUserCode(studentBaseInfo.getXh());
            libraryAccessRecord.setLibraryAccessTimes(outCollect.size());
            libraryAccessRecord.setLibraryAccessDuration(reduce);
            libraryAccessRecordsList.add(libraryAccessRecord);
        }
        for (LibraryAccessRecords libraryAccessRecords : libraryAccessRecordsList) {
            long count = reduceList.stream().filter(x -> x < libraryAccessRecords.getLibraryAccessDuration()).count();
            long rate = count/reduceList.size();
            libraryAccessRecord.setLibraryAccessBeatRate(rate);
        }
            DynamicDataSourceContextHolder.poll();
            insertLibraryAccessRecords(libraryAccessRecordsList);
        }

    @Transactional(rollbackFor = Exception.class)
    void insertLibraryAccessRecords( List<LibraryAccessRecords> libraryAccessRecords){
        DynamicDataSourceContextHolder.push("mysql1");
        this.saveBatch(libraryAccessRecords);
        DynamicDataSourceContextHolder.poll();
    }
}
